<!--
 * @Descripttion : 
 * @Autor        : Lilong
 * @Date         : 2022-10-08 16:07:07
 * @LastEditTime : 2022-10-09 07:26:45
 * @FilePath     : \src\App.vue
-->
<script setup lang="ts">
import {ref} from 'vue'

//ref声明基础类型数据
let num:number = 1                                                                    
let refNum = ref<number>(num)
const refStr = ref<string>('1')
const refBol = ref<boolean>(true)   //只能赋值true、false
const refNul = ref<null>(null)  //null只能赋值给null
const refUnde = ref<undefined>(undefined) //undefined只能赋值给undefined
const refUnkown = ref<unknown>(undefined) //其它基础类型都可以赋值给unknown类型
const refAny = ref<any>(undefined) //其它类型都可以赋值给any类型
const refNever = ref<never>()   //其它类型不能赋值给never类型，但never类型可以赋值给其它类型(never是其它类型的子类型)
const refSym = ref<Symbol>(Symbol(1))
// const refBig = ref<BigInt>(BigInt(Number.MIN_SAFE_INTEGER))    //BigInt暂时无法声明，可能需要其它库

console.log('refNum', refNum.value)
// console.log('refNul', refNul.value)   //null、undefined不能.value
console.log('refSym', refSym.value)

console.log('=============================')

//ref声明引用类型数据
type B = {
  id: number;
  name: string
}

let obj: B = {id: 1, name: 'front-refined'}

enum CommentStatusType {
  All,
  Pass,
  Wait
}
enum CommentStatusText {
  All = '全部',
  Pass = '已审核',
  Wait = '待审核'  
}

const COMMENT_STATUS_TEXTS = new Map<CommentStatusType, CommentStatusText>([
  [CommentStatusType.Wait, CommentStatusText.Wait],
  [CommentStatusType.Pass, CommentStatusText.Pass]
])

let arr: number[] = [1, 2, 3, 4]
let set1:Set<number> = new Set(arr)

let ma:number = Math.PI
let reg: RegExp = new RegExp(/^[0-9]*$/)
let time: Date = new Date()

const refArr = ref<Array<number>>([1, 2, 3])
const refObj = ref<B>(obj)
const refMap = ref<Map<CommentStatusType, CommentStatusText>>(COMMENT_STATUS_TEXTS)
const refSet = ref<Set<number>>(set1)
const refMath = ref<number>(ma)
const refReg = ref<RegExp>(reg)
const refTime = ref<Date>(time)

console.log('refArr', refArr)
console.log('refMap', refMap)
console.log('refSet', refSet)
console.log('refMath', refMath)
console.log('refReg', refReg)
console.log('refTime', refTime)

console.log('=============================')
/**
 * ref创建的数据：js中同各国.value访问，模板中无需.value
 */
refArr.value.push(1)
console.log('refArr', refArr)
refObj.value.id = 2
console.log('refObj', refObj)

console.log('=============================')
/***
 * ref对于基本类型：创建出来的数据和以前无关，与js中的基本类型表现一致
 * ref对于引用类型：创建出来的数据和以前相关，与js中的引用数据类型表现一致
 */
//基本类型，ref包裹前后相互不影响，相当于复制
console.log(num, refNum.value)  //1 1
num = 2
console.log(num, refNum.value)  //2 1
refNum.value = 3
console.log(num, refNum.value)  //2 3

//引用类型，ref包裹前后相互影响，相当于引用
console.log('obj.id', obj.id)   //obj.id 2
console.log('refObj.id', refObj.value.id) //refObj.id 2

refObj.value.id = 3
console.log('obj.id', obj.id)   //obj.id 3
console.log('refObj.id', refObj.value.id) //refObj.id 3

obj.id = 4
console.log('obj.id', obj.id)   //obj.id 4
console.log('refObj.id', refObj.value.id) //refObj.id 4


</script>

<template>
  <h3>ref：</h3>
  <h5>
    作用：常用于声明响应式基础类型的值(单个)，也可声明对象，声明对象时，内部会自动通过reactive转为代理对象
  </h5>
  <h5>
    注意：<br>
    1、ref声明的值，在模板中被访问时，会自动展开为内部值，无需.value；在js中，需.value <br>
    2、若用ref声明对象时，相当于用了reactive将对象转为深层次响应式对象 <br>
  </h5>
  <h5>
    建议：<br>
    1、基本类型值（String 、Nmuber 、Boolean 等）或单值对象（类似像 {count: 3} 这样只有一个属性值的对象）使用 ref <br>
    2、引用类型值（Object 、Array）使用 reactive
  </h5>
  <h5>
    区别： <br>
    1、本质角度：Ref的本质是通过Reactive创建的，Ref(10)=>Reactive({value:10})；Reactive的本质是将每一层的数都解析成proxy对象；ref相当于把值类型添加一层包装没变成响应式的引用类型的值，reactive则是引用类型的值变为响应式的值。 <br>
    2、使用角度：Ref在模板调用可以直接省略value，在js中改变变量的值需要修改value的值，才能修改成功；reactive在模板和js中都无需.value；<br>
    3、定义数据角度：ref 用来定义：基本类型数据或单值对象(类似像 {count: 3} 这样只有一个属性值的对象)；reactive 用来定义：对象（或数组）类型(引用类型)；ref 也可以用来定义对象（或数组）类型数据, 它内部会自动通过 reactive 转为代理对象 <br>
  </h5>
  <h6>声明基础类型</h6>
  <ul>  
    <li>Number类型：{{ refNum }}</li>
    <li>String类型：{{ refStr}}</li>
    <li>Boolean类型：{{ refBol }}</li> 
    <li>Null类型：{{ refNul}}</li>
    <li>Undefined类型：{{ refUnde}}</li>
    <li>Unkown类型：{{ refUnkown}}</li>
    <li>Any类型：{{ refAny}}</li>
    <li>Never类型：{{ refNever}}</li>
    <li>Symbol类型：{{ refSym}}</li>
  </ul>

  <h6>声明引用类型</h6>
  <ul>  
    <li>Array类型：{{ refArr }}</li>
    <li>Object类型：{{ refObj }}</li>
    <li>Map类型：{{ refMap }}</li>
    <li>Set类型：{{ refSet }}</li>   
    <li>Math类型：{{ refMath }}</li>
    <li>RegExp类型：{{ refReg }}</li>
    <li>Date类型：{{ refTime }}</li>
  </ul>
</template>

<style scoped>
ul,li{
  list-style: none;
}
</style>
